#include "config/config.h"
#include <fstream>
#include <iostream>
#include <filesystem>
#include <cstdlib>

namespace fs = std::filesystem;

namespace cpp_backend
{
    namespace config
    {

        Config &Config::Instance()
        {
            static Config instance;
            return instance;
        }

        bool Config::LoadFromFile(const std::string &config_file)
        {
            try
            {
                // 检查文件是否存在
                if (!fs::exists(config_file))
                {
                    std::cerr << "Config file not found: " << config_file;
                    return false;
                }

                // 读取文件内容
                std::ifstream ifs(config_file);
                if (!ifs.is_open())
                {
                    std::cerr << "Failed to open config file: " << config_file;
                    return false;
                }

                nlohmann::json j;
                ifs >> j;
                ifs.close();

                // 解析配置
                ParseFromJson(j);

                // 验证配置
                if (!ValidateConfig())
                {
                    std::cerr << "Invalid configuration";
                    return false;
                }

                LOG_INFO << "Configuration loaded from: " << config_file;
                return true;
            }
            catch (const std::exception &e)
            {
                std::cerr << "Failed to load config: " << e.what();
                return false;
            }
        }

        bool Config::LoadFromString(const std::string &json_str)
        {
            try
            {
                nlohmann::json j = nlohmann::json::parse(json_str);
                ParseFromJson(j);

                if (!ValidateConfig())
                {
                    std::cerr << "Invalid configuration";
                    return false;
                }

                return true;
            }
            catch (const std::exception &e)
            {
                std::cerr << "Failed to parse config: " << e.what();
                return false;
            }
        }

        bool Config::SaveToFile(const std::string &config_file) const
        {
            try
            {
                // 创建目录
                fs::path file_path(config_file);
                if (file_path.has_parent_path())
                {
                    fs::create_directories(file_path.parent_path());
                }

                // 写入文件
                std::ofstream ofs(config_file);
                if (!ofs.is_open())
                {
                    std::cerr << "Failed to create config file: " << config_file;
                    return false;
                }

                nlohmann::json j = ToJson();
                ofs << j.dump(4); // 格式化输出,缩进4空格
                ofs.close();

                LOG_INFO << "Configuration saved to: " << config_file;
                return true;
            }
            catch (const std::exception &e)
            {
                std::cerr << "Failed to save config: " << e.what();
                return false;
            }
        }

        void Config::ParseFromJson(const nlohmann::json &j)
        {
            // 解析服务器配置
            if (j.contains("server"))
            {
                const auto &server = j["server"];
                if (server.contains("host"))
                    server_config_.host = server["host"];
                if (server.contains("http_port"))
                    server_config_.http_port = server["http_port"];
                if (server.contains("websocket_port"))
                    server_config_.websocket_port = server["websocket_port"];
                if (server.contains("grpc_port"))
                    server_config_.grpc_port = server["grpc_port"];
                if (server.contains("thread_pool_size"))
                    server_config_.thread_pool_size = server["thread_pool_size"];
                if (server.contains("io_thread_count"))
                    server_config_.io_thread_count = server["io_thread_count"];
            }

            // 解析MySQL配置
            if (j.contains("database") && j["database"].contains("mysql"))
            {
                const auto &mysql = j["database"]["mysql"];
                if (mysql.contains("host"))
                    mysql_config_.host = mysql["host"];
                if (mysql.contains("port"))
                    mysql_config_.port = mysql["port"];
                if (mysql.contains("database"))
                    mysql_config_.database = mysql["database"];
                if (mysql.contains("username"))
                    mysql_config_.username = mysql["username"];
                if (mysql.contains("password"))
                    mysql_config_.password = mysql["password"];
                if (mysql.contains("pool_size"))
                    mysql_config_.pool_size = mysql["pool_size"];
                if (mysql.contains("connect_timeout"))
                    mysql_config_.connect_timeout = mysql["connect_timeout"];
            }

            // 解析Redis配置
            if (j.contains("database") && j["database"].contains("redis"))
            {
                const auto &redis = j["database"]["redis"];
                if (redis.contains("host"))
                    redis_config_.host = redis["host"];
                if (redis.contains("port"))
                    redis_config_.port = redis["port"];
                if (redis.contains("password"))
                    redis_config_.password = redis["password"];
                if (redis.contains("pool_size"))
                    redis_config_.pool_size = redis["pool_size"];
                if (redis.contains("connect_timeout"))
                    redis_config_.connect_timeout = redis["connect_timeout"];
                if (redis.contains("db_index"))
                    redis_config_.db_index = redis["db_index"];
            }

            // 解析存储配置
            if (j.contains("storage"))
            {
                const auto &storage = j["storage"];
                if (storage.contains("upload_path"))
                    storage_config_.upload_path = storage["upload_path"];
                if (storage.contains("max_file_size"))
                    storage_config_.max_file_size = storage["max_file_size"];
                if (storage.contains("chunk_size"))
                    storage_config_.chunk_size = storage["chunk_size"];
                if (storage.contains("enable_deduplication"))
                    storage_config_.enable_deduplication = storage["enable_deduplication"];
            }

            // 解析JWT配置
            if (j.contains("jwt"))
            {
                const auto &jwt = j["jwt"];
                if (jwt.contains("secret"))
                    jwt_config_.secret = jwt["secret"];
                if (jwt.contains("expire_seconds"))
                    jwt_config_.expire_seconds = jwt["expire_seconds"];
            }
            if (const char *env_jwt_secret = std::getenv("JWT_SECRET"))
            {
                jwt_config_.secret = env_jwt_secret;
            }
            // logger解析
            if (j.contains("logger"))
            {
                const auto &logger = j["logger"];
                if (logger.contains("moduleName"))
                {
                    log_config_.moduleName = logger["mouduleName"];
                }
                if (logger.contains("logDirectory"))
                {
                    log_config_.logDirectory = logger["logDirectory"];
                }
                if (logger.contains("maxFileSize"))
                {

                    log_config_.maxFileSize = logger::LoggerManager::getInstance().parseFileSize(logger["maxFileSize"]);
                }
                if (logger.contains("flushInterval"))
                {
                    log_config_.flushInterval = logger["flushInterval"];
                }
                if (logger.contains("minlevel"))
                {
                    auto level = logger["minlevel"];
                    if (level == "TRACE")
                    {
                        log_config_.minLevel = logger::LogLevel::TRACE_LEVEL;
                    }
                    else if (level == "DEBUG")
                    {
                        log_config_.minLevel = logger::LogLevel::DEBUG_LEVEL;
                    }
                    else if (level == "INFO")
                    {
                        log_config_.minLevel = logger::LogLevel::INFO_LEVEL;
                    }
                    else if (level == "WARN")
                    {
                        log_config_.minLevel = logger::LogLevel::WARN_LEVEL;
                    }
                    else if (level == "ERROR")
                    {
                        log_config_.minLevel = logger::LogLevel::ERROR_LEVEL;
                    }
                    else if (level == "FATAL")
                    {
                        log_config_.minLevel = logger::LogLevel::FATAL_LEVEL;
                    }
                    else
                    {
                    }
                }
                if (logger.contains("anasyncMode"))
                {
                    log_config_.asyncMode = logger["asyncMode"];
                }
                if (logger.contains("consoleOutput"))
                {
                    log_config_.consoleOutput = logger["consoleOutput"];
                }
            }

            // 解析监控配置
            if (j.contains("monitor"))
            {
                const auto &monitor = j["monitor"];
                if (monitor.contains("enable"))
                    monitor_config_.enable = monitor["enable"];
                if (monitor.contains("report_interval"))
                    monitor_config_.report_interval = monitor["report_interval"];
                if (monitor.contains("enable_prometheus"))
                    monitor_config_.enable_prometheus = monitor["enable_prometheus"];
                if (monitor.contains("prometheus_port"))
                    monitor_config_.prometheus_port = monitor["prometheus_port"];
            }
        }

        nlohmann::json Config::ToJson() const
        {
            nlohmann::json j;

            // 服务器配置
            j["server"]["host"] = server_config_.host;
            j["server"]["http_port"] = server_config_.http_port;
            j["server"]["websocket_port"] = server_config_.websocket_port;
            j["server"]["grpc_port"] = server_config_.grpc_port;
            j["server"]["thread_pool_size"] = server_config_.thread_pool_size;
            j["server"]["io_thread_count"] = server_config_.io_thread_count;

            // MySQL配置
            j["database"]["mysql"]["host"] = mysql_config_.host;
            j["database"]["mysql"]["port"] = mysql_config_.port;
            j["database"]["mysql"]["database"] = mysql_config_.database;
            j["database"]["mysql"]["username"] = mysql_config_.username;
            j["database"]["mysql"]["password"] = mysql_config_.password;
            j["database"]["mysql"]["pool_size"] = mysql_config_.pool_size;
            j["database"]["mysql"]["connect_timeout"] = mysql_config_.connect_timeout;

            // Redis配置
            j["database"]["redis"]["host"] = redis_config_.host;
            j["database"]["redis"]["port"] = redis_config_.port;
            j["database"]["redis"]["password"] = redis_config_.password;
            j["database"]["redis"]["pool_size"] = redis_config_.pool_size;
            j["database"]["redis"]["connect_timeout"] = redis_config_.connect_timeout;
            j["database"]["redis"]["db_index"] = redis_config_.db_index;

            // 存储配置
            j["storage"]["upload_path"] = storage_config_.upload_path;
            j["storage"]["max_file_size"] = storage_config_.max_file_size;
            j["storage"]["chunk_size"] = storage_config_.chunk_size;
            j["storage"]["enable_deduplication"] = storage_config_.enable_deduplication;

            // JWT配置
            j["jwt"]["secret"] = jwt_config_.secret;
            j["jwt"]["expire_seconds"] = jwt_config_.expire_seconds;

            // logger 配置
            j["logger"]["moduleName"] = log_config_.moduleName;
            j["logger"]["logDirectory"] = log_config_.logDirectory;
            j["logger"]["maxFileSize"] = log_config_.maxFileSize;
            j["logger"]["flushInterval"] = log_config_.flushInterval;
            j["logger"]["minlevel"] = log_config_.minLevel;
            j["logger"]["asyncMode"] = log_config_.asyncMode;
            j["logger"]["consoleOutput"] = log_config_.consoleOutput;

            // 监控配置
            j["monitor"]["enable"] = monitor_config_.enable;
            j["monitor"]["report_interval"] = monitor_config_.report_interval;
            j["monitor"]["enable_prometheus"] = monitor_config_.enable_prometheus;
            j["monitor"]["prometheus_port"] = monitor_config_.prometheus_port;

            return j;
        }

        bool Config::ValidateConfig() const
        {
            // 验证端口号
            if (server_config_.http_port <= 0 || server_config_.http_port > 65535)
            {
                std::cerr << "Invalid HTTP port: " << server_config_.http_port;
                return false;
            }

            if (server_config_.websocket_port <= 0 || server_config_.websocket_port > 65535)
            {
                std::cerr << "Invalid WebSocket port: " << server_config_.websocket_port;
                return false;
            }

            // 验证线程池大小
            if (server_config_.thread_pool_size <= 0)
            {
                std::cerr << "Invalid thread pool size: " << server_config_.thread_pool_size;
                return false;
            }

            // 验证数据库配置
            if (mysql_config_.host.empty() || mysql_config_.database.empty())
            {
                std::cerr << "MySQL host or database is empty";
                return false;
            }

            if (redis_config_.host.empty())
            {
                std::cerr << "Redis host is empty";
                return false;
            }

            // 验证存储配置
            if (storage_config_.upload_path.empty())
            {
                std::cerr << "Upload path is empty";
                return false;
            }

            if (storage_config_.max_file_size <= 0)
            {
                std::cerr << "Invalid max file size: " << storage_config_.max_file_size;
                return false;
            }

            // 验证JWT配置
            if (jwt_config_.secret.empty())
            {
                std::cerr << "JWT secret is empty";
                return false;
            }

            return true;
        }

        void Config::PrintConfig() const
        {
            auto &log_instance = logger::LoggerManager::getInstance();
            log_instance.init(log_config_);
            LOG_INFO << "\n========== Configuration ==========";

            LOG_INFO << "[Server]";
            LOG_INFO << "  Host: " << server_config_.host;
            LOG_INFO << "  HTTP Port: " << server_config_.http_port;
            LOG_INFO << "  WebSocket Port: " << server_config_.websocket_port;
            LOG_INFO << "  gRPC Port: " << server_config_.grpc_port;
            LOG_INFO << "  Thread Pool Size: " << server_config_.thread_pool_size;

            LOG_INFO << "[MySQL]";
            LOG_INFO << "  Host: " << mysql_config_.host << ":" << mysql_config_.port;
            LOG_INFO << "  Database: " << mysql_config_.database;
            LOG_INFO << "  Username: " << mysql_config_.username;
            LOG_INFO << "  Pool Size: " << mysql_config_.pool_size;

            LOG_INFO << "[Redis]";
            LOG_INFO << "  Host: " << redis_config_.host << ":" << redis_config_.port;
            LOG_INFO << "  DB Index: " << redis_config_.db_index;
            LOG_INFO << "  Pool Size: " << redis_config_.pool_size;

            LOG_INFO << "[Storage]";
            LOG_INFO << "  Upload Path: " << storage_config_.upload_path;
            LOG_INFO << "  Max File Size: " << storage_config_.max_file_size / 1024 / 1024 << " MB";
            LOG_INFO << "  Chunk Size: " << storage_config_.chunk_size / 1024 / 1024 << " MB";
            LOG_INFO << "  Enable Deduplication: " << (storage_config_.enable_deduplication ? "Yes" : "No");

            LOG_INFO << "[JWT]";
            LOG_INFO << "  Secret: ******"; // 隐藏敏感信息
            LOG_INFO << "  Expire: " << jwt_config_.expire_seconds << " seconds";

            LOG_INFO << "[Monitor]";
            LOG_INFO << "  Enable: " << (monitor_config_.enable ? "Yes" : "No");
            LOG_INFO << "  Report Interval: " << monitor_config_.report_interval << " seconds";

            LOG_INFO << "==================================\n";
        }

    } // namespace config
} // namespace file_server
